package com.hxd.otc.utils.download;

import android.app.Activity;
import android.app.Dialog;
import android.app.DownloadManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.view.View;

import com.hxd.otc.BuildConfig;
import com.hxd.otc.R;
import com.hxd.otc.base.BaseApplication;
import com.hxd.otc.common.SpConfig;
import com.hxd.otc.dialog.UpdateVersionDialog;
import com.hxd.otc.module.my.bean.AppInfoBean;
import com.hxd.otc.utils.CommonUtil;
import com.hxd.otc.utils.LogUtils;
import com.hxd.otc.utils.SpUtil;

import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by lzy on 2018/7/2 0002.
 * description ${版本更新工具}
 */
public class DownloadManagerUtil {

    private DownloadManagerUtil() {
    }

    /**
     * 校验版本信息
     *
     * @param newVersionBean 新版本信息
     * @param isInitiative   是否主动获取新版本
     */
    public static boolean hasNewVersion(AppInfoBean newVersionBean, boolean isInitiative) {
        if (newVersionBean == null) return false;
        int newVersionCode = newVersionBean.getVersionValue();
        if (newVersionCode <= CommonUtil.getVersionCode()) return false;
        if (newVersionBean.getIsUpgrade() == 1) return true;
        if (isInitiative) return true;
        int ignoreVersionCode = SpUtil.PERMANENT.getInt(SpConfig.Permanent.IGNORE_VERSION_CODE, 0);
        return ignoreVersionCode == 0 || newVersionCode > ignoreVersionCode;
    }

    /**
     * 显示提示更新版本对话框
     *
     * @param activity
     * @param newVersionBean
     * @return
     */
    public static Dialog showUpdateVersionDialog(final Activity activity, final AppInfoBean newVersionBean) {
        UpdateVersionDialog updateVersionDialog = new UpdateVersionDialog(activity);
        updateVersionDialog.setAppInfo(newVersionBean).show();
        return updateVersionDialog;
    }

    @NonNull
    private static AlertDialog createUpdateDialog(Activity activity, final AppInfoBean newVersionBean) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        final boolean isForced = newVersionBean.getIsUpgrade() == 1;

        builder.setTitle(R.string.my_version_updating)
                .setMessage("")
                .setCancelable(!isForced)
                .setPositiveButton(isForced ? R.string.my_update_now : R.string.my_update, null);

        //强制更新不显示取消按钮，非强制更新显示
        if (!isForced) {
            builder.setNegativeButton(R.string.my_temporarily_not_update, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,
                                    int whichButton) {
                    SpUtil.PERMANENT.putInt(SpConfig.Permanent.IGNORE_VERSION_CODE, newVersionBean.getVersionValue());
                    dialog.dismiss();
                }
            });
        }
        final AlertDialog dialog = builder.create();
        dialog.show();
        //通过该方式实现可以避免点击确定时默认调用dismiss方法，因为强制更新不应该关闭对话框
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                long downloadId = DownloadManagerUtil.downloadApk(newVersionBean);
//                SpUtil.PERMANENT.putObject(SpConfig.Permanent.DOWNLOAD_INFO, new DownloadInfoBean(downloadId, newVersionBean.getSaveName()));
//                BlocksToast.get().showToast(R.string.my_start_download_msg);
                Intent intent= new Intent();
                intent.setAction("android.intent.action.VIEW");
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                Uri content_url = Uri.parse(newVersionBean.getAddress());
                intent.setData(content_url);
                getContext().startActivity(intent);
                if (!isForced) dialog.dismiss();
            }
        });
        return dialog;
    }


    /**
     * 创建安装对话框
     *
     * @param activity
     * @param newVersionBean 新版本信息
     * @return
     */
    public static AlertDialog createInstallDialog(Activity activity, final AppInfoBean newVersionBean) {
        final boolean isForced = newVersionBean.getIsUpgrade() == 1;
        AlertDialog.Builder builder = new AlertDialog.Builder(activity)
                .setTitle(R.string.my_version_updating)
                .setMessage(R.string.my_install_dialog_message)
                .setCancelable(!isForced)
                .setPositiveButton(R.string.my_install_dialog_yes, null);
        if (!isForced) {
            builder.setNegativeButton(R.string.my_install_dialog_no, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    SpUtil.PERMANENT.putInt(SpConfig.Permanent.IGNORE_VERSION_CODE, newVersionBean.getVersionValue());
                    dialog.dismiss();
                }
            });
        }

        final AlertDialog dialog = builder.create();
        dialog.show();
        //通过该方式实现可以避免点击确定时默认调用dismiss方法，因为强制更新不应该关闭对话框
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                installApk(newVersionBean.getSaveName());
                if (!isForced) dialog.dismiss();
            }
        });
        return dialog;
    }

    /**
     * 获取文件的uri，适配7.0
     *
     * @param file
     * @return
     */
    public static Uri getUri(File file) {
        return Build.VERSION.SDK_INT >= 24 ? FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".provider", file) : Uri.fromFile(file);
    }

    /**
     * 下载新版本apk
     *
     * @param versionBean
     * @return
     */
    public static long downloadApk(AppInfoBean versionBean) {
        Uri uri = Uri.parse(versionBean.getAddress());
        DownloadManager.Request req = new DownloadManager.Request(uri);
        //设置WIFI下进行更新
        //req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
        //下载中和下载完后都显示通知栏
        req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
        //使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0
        req.setDestinationInExternalFilesDir(getContext(), Environment.DIRECTORY_DOWNLOADS, versionBean.getSaveName());
        //通知栏标题
        req.setTitle(versionBean.getSaveName());
        //通知栏描述信息
        req.setDescription(versionBean.getType());
        //设置类型为.apk
        req.setMimeType("application/vnd.android.package-archive");
        //获取下载任务ID
        DownloadManager downloadManager = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
        assert downloadManager != null;
        return downloadManager.enqueue(req);
    }

    /**
     * 下载前先移除前一个任务，防止重复下载
     *
     * @param downloadId
     */
    public static void clearCurrentTask(long downloadId) {
        try {
            DownloadManager downloadManager = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
            downloadManager.remove(downloadId);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * @param simpleFileName 下载目录下文件名
     * @return 文件是否存在
     */
    public static boolean existsOfDownFile(String simpleFileName) {
        return getDownloadFile(simpleFileName).exists();
    }

    /**
     * 获取下载目录下载的file
     *
     * @param simpleFileName 下载目录下文件名
     * @return
     */
    @NonNull
    public static File getDownloadFile(String simpleFileName) {
        return new File(getContext().getExternalFilesDir("Download"), simpleFileName);
    }

    /**
     * 删除下载目录下问文件
     */
    public static void deleteDownloadFiles() {
        File downloadDir = getContext().getExternalFilesDir("Download");
        if (downloadDir == null || !downloadDir.exists()) return;
        for (File file : downloadDir.listFiles()) {
            file.delete();
        }
    }

    /**
     * 文件是否下载成功
     *
     * @param downloadId
     * @return
     */
    public static boolean isDownloadSuccessful(long downloadId) {
        DownloadManager downloadManager = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
        assert downloadManager != null;

        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor c = downloadManager.query(query);
        if (c == null || !c.moveToFirst()) return false;
        int status = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
        c.close();
        return status == DownloadManager.STATUS_SUCCESSFUL;
    }

    /**
     * 查询下载进度
     *
     * @param downloadId
     * @param onDownloadListener
     */
    public static void query(final long downloadId, final OnDownloadListener onDownloadListener) {
        final DownloadManager downloadManager = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
        final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
                assert downloadManager != null;
                Cursor c = downloadManager.query(query);
                if (c == null || !c.moveToFirst()) return;
                int status = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
                switch (status) {
                    case DownloadManager.STATUS_PENDING://等待下载
                        if (onDownloadListener != null) onDownloadListener.onPending();
                        break;
                    case DownloadManager.STATUS_PAUSED://暂停
                        if (onDownloadListener != null) onDownloadListener.onPaused();
                        break;
                    case DownloadManager.STATUS_RUNNING://进行中
                        if (onDownloadListener != null) onDownloadListener.onRunning(
                                c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)),
                                c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)));
                        break;
                    case DownloadManager.STATUS_SUCCESSFUL:
                        if (c.moveToFirst()) {
                            installApk(downloadId);
                            scheduledExecutorService.shutdown();
                        }
                        c.close();
                        if (onDownloadListener != null) onDownloadListener.onSuccessful();
                        break;
                    case DownloadManager.STATUS_FAILED:
                        if (onDownloadListener != null) onDownloadListener.onFailed();
                        break;
                }
                c.close();
            }
        }, 0, 1, TimeUnit.SECONDS);
    }


    /**
     * 通过下载id安装apk,存在兼容问题，在华为部分手机会有异常，无法调用
     *
     * @param downloadApkId
     */
    @Deprecated
    private static void installApk(long downloadApkId) {
        DownloadManager dManager = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
        assert dManager != null;
        Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);
        installApk(downloadFileUri);
    }

    /**
     * 通过文件名安装下载目录下的apk
     *
     * @param fileName 文件名
     */
    public static void installApk(String fileName) {
        installApk(getUri(getDownloadFile(fileName)));
    }

    /**
     * 安装指定uri的apk
     *
     * @param downloadFileUri
     */
    public static void installApk(Uri downloadFileUri) {
        try {
            Intent install = new Intent(Intent.ACTION_VIEW);
            if (downloadFileUri != null) {
                install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
                install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                getContext().startActivity(install);
            } else {
                LogUtils.e("download error");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Context getContext() {
        return BaseApplication.getInstance();
    }
}

